package com.vonchenchen.renderer;

import android.app.Service;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.ImageFormat;
import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import static android.graphics.ImageFormat.NV21;
import static android.graphics.ImageFormat.YUV_420_888;
import static android.graphics.ImageFormat.YUY2;
import static android.graphics.ImageFormat.YV12;

/**
 * Created by lidechen on 2021/1/27.
 */
public abstract class VideoCapture {

    private static final int kVideoI420 = 0;
    private static final int kVideoYV12 = 1;
    private static final int kVideoYUY2 = 2;
    private static final int kVideoNV12 = 11;
    private static final int kVideoNV21 = 12;
    private static final int kVideoUnknown = 99;

    protected int mCameraNativeOrientation;

    protected final Context mContext;
    protected final int mId;
    protected long mNativeVideoCaptureDeviceAndroid;
    private int mLastRotation = -1;

    VideoCapture(Context context, int id, long nativeVideoCaptureDeviceAndroid) {
        this.mContext = context;
        this.mId = id;
        this.mNativeVideoCaptureDeviceAndroid = nativeVideoCaptureDeviceAndroid;
    }

    public abstract int allocate();

    public abstract int setCaptureFormat(int format);

    public abstract int startCapture(int width, int height, int frameRate);

    public abstract int stopCapture();

    public abstract boolean isTorchSupported();

    public abstract boolean isFocusSupported();

    public abstract boolean isZoomSupported();

    public abstract boolean isAutoFaceFocusSupported();

    public abstract int setZoom(float zoomValue);

    public abstract float getMaxZoom();

    public abstract int setTorchMode(boolean isTorchOn);

    public abstract int setFocus(float x, float y, boolean inPreview);

    public abstract int setAutoFaceFocus(boolean enable);

    public abstract boolean isExposureSupported();

    public abstract int setExposure(float x, float y, boolean inPreview);

    public abstract int UnRegisterNativeHandle();

    public abstract void deallocate();

//use for camera1 camera2
//    public native void ProvideCameraFrame(byte[] data, int length, long nativeVideoCaptureDeviceAndroid);
public void ProvideCameraFrame(byte[] data, int length, long nativeVideoCaptureDeviceAndroid){}
//    public native void ProvideCameraTexture(byte[] data, int textureID, long nativeVideoCaptureDeviceAndroid);
//    public native boolean isAutoFaceFocusEnabled(long nativeVideoCaptureDeviceAndroid);
public boolean isAutoFaceFocusEnabled(long nativeVideoCaptureDeviceAndroid){ return false; }
//    public native void NotifyCameraFocusAreaChanged(float x, float y, float width, float height, long nativeVideoCaptureDeviceAndroid);
public void NotifyCameraFocusAreaChanged(float x, float y, float width, float height, long nativeVideoCaptureDeviceAndroid){}
//    public native void NotifyCameraExposureAreaChanged(float x, float y, float width, float height, long nativeVideoCaptureDeviceAndroid);
public void NotifyCameraExposureAreaChanged(float x, float y, float width, float height, long nativeVideoCaptureDeviceAndroid) {}

//use for camera2
//    public native void onCameraError(long nativeVideoCaptureDeviceAndroid, String message);
public void onCameraError(long nativeVideoCaptureDeviceAndroid, String message){}

    public static String fetchCapability(int id, Context appContext, String captureName) {
        String PREFS_NAME = "CamCaps2";
        SharedPreferences caps = appContext.getSharedPreferences(PREFS_NAME, 0);
        String capture_name = caps.getString("CaptureName", (String)null);
        if (capture_name != null && capture_name.equals(captureName)) {
            return caps.getString("Cam_" + id, (String)null);
        } else {
            SharedPreferences.Editor editor = caps.edit();
            editor.clear();
            editor.commit();
            return null;
        }
    }

    public static void cacheCapability(int id, Context appContext, String cap, String captureName) {
        String PREFS_NAME = "CamCaps2";
        SharedPreferences caps = appContext.getSharedPreferences(PREFS_NAME, 0);
        SharedPreferences.Editor editor = caps.edit();
        editor.putString("Cam_" + id, cap);
        editor.putString("CaptureName", captureName);
        editor.commit();
    }

    public static int translateToEngineFormat(int fmt) {
        switch(fmt) {
            case 17:
                return 12;
            case 20:
                return 2;
            case 35:
                return 0;
            case 842094169:
                return 1;
            default:
                return 99;
        }
    }

    public static int translateToAndroidFormat(int fmt) {
        switch(fmt) {
            case 0:
                //return 35;
                return YUV_420_888;
            case 1:
                //return 842094169;
                return YV12;
            case 2:
                //return 20;
                return YUY2;
            case 12:
                //return 17;
                return NV21;
            default:
                return 0;
        }
    }

    public static boolean isEmulator() {
        if (!"nokia".equalsIgnoreCase(Build.MANUFACTURER) || !"Nokia_N1".equalsIgnoreCase(Build.DEVICE) && !"N1".equalsIgnoreCase(Build.MODEL)) {
            String result = "";

            try {
                String[] args = new String[]{"/system/bin/cat", "/proc/cpuinfo"};
                ProcessBuilder cmd = new ProcessBuilder(args);
                Process process = cmd.start();
                StringBuffer sb = new StringBuffer();
                String readLine = "";
                BufferedReader responseReader = new BufferedReader(new InputStreamReader(process.getInputStream(), "utf-8"));

                while((readLine = responseReader.readLine()) != null) {
                    sb.append(readLine);
                }

                responseReader.close();
                result = sb.toString().toLowerCase();
                return result.contains("intel") || result.contains("amd");
            } catch (IOException var7) {
                return false;
            }
        } else {
            return false;
        }
    }

    private int checkOrientation() {
        if (this.mContext != null && this.mContext.getSystemService(Service.WINDOW_SERVICE) != null) {
            Display display = ((WindowManager)((WindowManager)this.mContext.getSystemService(Service.WINDOW_SERVICE))).getDefaultDisplay();
            if (display != null) {
                try {
                    int orientation = display.getRotation();
                    return orientation;
                } catch (RuntimeException var3) {
                    Log.e("VideoCapture", "video capture checkOrientation display getRotation throwout exception");
                    return this.mLastRotation;
                }
            }
        }

        return this.mLastRotation;
    }
}
